# file: D:\python-project\Well_Data_visualization_program\曹锋\src\ui\display_options_dialog.py
from PySide6.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
    QComboBox, QSpinBox, QDoubleSpinBox, QCheckBox, QGridLayout,
    QGroupBox, QSlider, QWidget, QTabWidget, QRadioButton, QColorDialog
)
from PySide6.QtGui import QColor, QPalette, QIcon, QPixmap
from PySide6.QtCore import Qt, Signal
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap


class DisplayOptionsDialog(QDialog):
    """曲线显示设置对话框"""

    # 预设颜色
    PRESET_COLORS = [
        "#FF5733", "#3357FF", "#33FF57", "#FF33F7", "#33FFF7",
        "#F7FF33", "#FF9933", "#9933FF", "#33FF99", "#FF3333"
    ]

    # 预设标记
    PRESET_MARKERS = [
        "None", "o", "s", "^", "D", "x", "+", "*", "v", ">"
    ]

    # 预设线型
    PRESET_LINESTYLES = [
        "-", "--", "-.", ":",
    ]

    def __init__(self, well_name, curve_name, parent=None, default_options=None):
        super().__init__(parent)
        self.setWindowTitle(f"{well_name} - {curve_name} 显示设置")
        self.resize(400, 500)

        # 设置默认选项
        self.options = {
            "color": "#FF5733",
            "plot_type": "曲线图",
            "line_width": 2,
            "line_style": "-",
            "marker": "None",
            "marker_size": 5,
            "opacity": 1.0,
            "show_grid": True,
            "fill_between": False,
            "normalize": False,
            "log_scale": False,
            "colormap": "viridis",
            "invert_y": False,
            "depth_range": "auto",  # 'auto' 或 [min, max]
            "value_range": "auto",  # 'auto' 或 [min, max]
        }

        # 如果提供了默认选项，则更新
        if default_options:
            self.options.update(default_options)

        # 初始化UI
        self._init_ui()

    def _init_ui(self):
        """初始化用户界面"""
        main_layout = QVBoxLayout(self)

        # 创建选项卡控件
        tab_widget = QTabWidget()

        # 基础设置选项卡
        tab_widget.addTab(self._create_basic_tab(), "基础设置")

        # 高级设置选项卡
        tab_widget.addTab(self._create_advanced_tab(), "高级设置")

        # 范围设置选项卡
        tab_widget.addTab(self._create_range_tab(), "范围设置")

        main_layout.addWidget(tab_widget)

        # 按钮区域
        btn_layout = QHBoxLayout()
        confirm_btn = QPushButton("确认")
        cancel_btn = QPushButton("取消")

        confirm_btn.clicked.connect(self.accept)
        cancel_btn.clicked.connect(self.reject)

        btn_layout.addStretch()
        btn_layout.addWidget(confirm_btn)
        btn_layout.addWidget(cancel_btn)
        main_layout.addLayout(btn_layout)

    def _create_basic_tab(self):
        """创建基础设置选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)

        # 颜色选择
        color_group = QGroupBox("曲线外观")
        color_layout = QGridLayout(color_group)

        # 颜色选择器
        color_label = QLabel("曲线颜色:")
        self.color_combo = QComboBox()

        # 添加预设颜色
        for color in self.PRESET_COLORS:
            pixmap = QPixmap(20, 20)
            pixmap.fill(QColor(color))
            icon = QIcon(pixmap)
            self.color_combo.addItem(icon, "")
            self.color_combo.setItemData(self.color_combo.count() - 1, color, Qt.DecorationRole)
            self.color_combo.setItemData(self.color_combo.count() - 1, color, Qt.ToolTipRole)

        # 添加自定义颜色选项
        self.color_combo.addItem("自定义...")

        # 设置当前颜色
        current_color_idx = self.PRESET_COLORS.index(self.options["color"]) if self.options[
                                                                                   "color"] in self.PRESET_COLORS else len(
            self.PRESET_COLORS)
        self.color_combo.setCurrentIndex(current_color_idx)

        self.color_combo.currentIndexChanged.connect(self._on_color_changed)

        color_layout.addWidget(color_label, 0, 0)
        color_layout.addWidget(self.color_combo, 0, 1)

        # 图表类型选择
        type_label = QLabel("图表类型:")
        self.plot_type_combo = QComboBox()
        self.plot_type_combo.addItems(["曲线图", "柱状图", "散点图", "热力图"])
        self.plot_type_combo.setCurrentText(self.options["plot_type"])
        self.plot_type_combo.currentTextChanged.connect(self._update_plot_options)

        color_layout.addWidget(type_label, 1, 0)
        color_layout.addWidget(self.plot_type_combo, 1, 1)

        layout.addWidget(color_group)

        # 线条设置
        line_group = QGroupBox("线条设置")
        line_layout = QGridLayout(line_group)

        # 线宽设置
        line_width_label = QLabel("线宽:")
        self.line_width_spin = QSpinBox()
        self.line_width_spin.setRange(1, 10)
        self.line_width_spin.setValue(self.options["line_width"])
        self.line_width_spin.setSuffix(" px")

        line_layout.addWidget(line_width_label, 0, 0)
        line_layout.addWidget(self.line_width_spin, 0, 1)

        # 线型设置
        line_style_label = QLabel("线型:")
        self.line_style_combo = QComboBox()
        self.line_style_combo.addItems(self.PRESET_LINESTYLES)
        self.line_style_combo.setCurrentText(self.options["line_style"])

        line_layout.addWidget(line_style_label, 1, 0)
        line_layout.addWidget(self.line_style_combo, 1, 1)

        layout.addWidget(line_group)

        # 标记设置
        marker_group = QGroupBox("标记设置")
        marker_layout = QGridLayout(marker_group)

        # 标记类型
        marker_label = QLabel("标记类型:")
        self.marker_combo = QComboBox()
        self.marker_combo.addItems(self.PRESET_MARKERS)
        self.marker_combo.setCurrentText(self.options["marker"])

        marker_layout.addWidget(marker_label, 0, 0)
        marker_layout.addWidget(self.marker_combo, 0, 1)

        # 标记大小
        marker_size_label = QLabel("标记大小:")
        self.marker_size_spin = QSpinBox()
        self.marker_size_spin.setRange(1, 20)
        self.marker_size_spin.setValue(self.options["marker_size"])
        self.marker_size_spin.setSuffix(" px")

        marker_layout.addWidget(marker_size_label, 1, 0)
        marker_layout.addWidget(self.marker_size_spin, 1, 1)

        layout.addWidget(marker_group)

        return tab

    def _create_advanced_tab(self):
        """创建高级设置选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)

        # 显示选项
        display_group = QGroupBox("显示选项")
        display_layout = QGridLayout(display_group)

        # 显示网格
        self.show_grid_check = QCheckBox("显示网格")
        self.show_grid_check.setChecked(self.options["show_grid"])

        # 填充区域
        self.fill_between_check = QCheckBox("填充区域")
        self.fill_between_check.setChecked(self.options["fill_between"])

        # 反转Y轴
        self.invert_y_check = QCheckBox("反转Y轴(深度向下)")
        self.invert_y_check.setChecked(self.options["invert_y"])

        display_layout.addWidget(self.show_grid_check, 0, 0)
        display_layout.addWidget(self.fill_between_check, 0, 1)
        display_layout.addWidget(self.invert_y_check, 1, 0)

        layout.addWidget(display_group)

        # 数据处理选项
        process_group = QGroupBox("数据处理")
        process_layout = QGridLayout(process_group)

        # 归一化
        self.normalize_check = QCheckBox("归一化数据")
        self.normalize_check.setChecked(self.options["normalize"])

        # 对数刻度
        self.log_scale_check = QCheckBox("使用对数刻度")
        self.log_scale_check.setChecked(self.options["log_scale"])

        process_layout.addWidget(self.normalize_check, 0, 0)
        process_layout.addWidget(self.log_scale_check, 0, 1)

        layout.addWidget(process_group)

        # 透明度设置
        opacity_group = QGroupBox("透明度")
        opacity_layout = QHBoxLayout(opacity_group)

        opacity_label = QLabel("透明度:")
        self.opacity_slider = QSlider(Qt.Horizontal)
        self.opacity_slider.setRange(10, 100)
        self.opacity_slider.setValue(int(self.options["opacity"] * 100))

        self.opacity_value = QLabel(f"{self.options['opacity']:.1f}")

        self.opacity_slider.valueChanged.connect(
            lambda: self.opacity_value.setText(f"{self.opacity_slider.value() / 100:.1f}"))

        opacity_layout.addWidget(opacity_label)
        opacity_layout.addWidget(self.opacity_slider)
        opacity_layout.addWidget(self.opacity_value)

        layout.addWidget(opacity_group)

        # 热力图颜色映射
        cmap_group = QGroupBox("热力图颜色映射")
        cmap_layout = QHBoxLayout(cmap_group)

        cmap_label = QLabel("颜色映射:")
        self.cmap_combo = QComboBox()

        # 添加常用的matplotlib颜色映射
        cmaps = ["viridis", "plasma", "inferno", "magma", "cividis",
                 "jet", "rainbow", "cool", "hot", "autumn", "winter"]
        self.cmap_combo.addItems(cmaps)
        self.cmap_combo.setCurrentText(self.options["colormap"])

        cmap_layout.addWidget(cmap_label)
        cmap_layout.addWidget(self.cmap_combo)

        # 仅在选择热力图时启用
        cmap_group.setEnabled(self.options["plot_type"] == "热力图")

        layout.addWidget(cmap_group)

        # 连接信号
        self.plot_type_combo.currentTextChanged.connect(lambda text: cmap_group.setEnabled(text == "热力图"))

        return tab

    def _create_range_tab(self):
        """创建范围设置选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)

        # 深度范围设置
        depth_group = QGroupBox("深度范围")
        depth_layout = QGridLayout(depth_group)

        self.depth_auto_radio = QRadioButton("自动")
        self.depth_manual_radio = QRadioButton("手动")

        self.depth_min_spin = QDoubleSpinBox()
        self.depth_max_spin = QDoubleSpinBox()

        self.depth_min_spin.setRange(-1000, 10000)
        self.depth_max_spin.setRange(-1000, 10000)

        self.depth_min_spin.setDecimals(2)
        self.depth_max_spin.setDecimals(2)

        # 设置当前值
        if self.options["depth_range"] == "auto":
            self.depth_auto_radio.setChecked(True)
        else:
            self.depth_manual_radio.setChecked(True)
            self.depth_min_spin.setValue(self.options["depth_range"][0])
            self.depth_max_spin.setValue(self.options["depth_range"][1])

        # 连接信号
        self.depth_auto_radio.toggled.connect(lambda checked: self.depth_min_spin.setEnabled(not checked))
        self.depth_auto_radio.toggled.connect(lambda checked: self.depth_max_spin.setEnabled(not checked))
        self.depth_min_spin.valueChanged.connect(self._validate_depth_range)
        self.depth_max_spin.valueChanged.connect(self._validate_depth_range)

        depth_layout.addWidget(self.depth_auto_radio, 0, 0)
        depth_layout.addWidget(QLabel("最小深度:"), 1, 0)
        depth_layout.addWidget(self.depth_min_spin, 1, 1)
        depth_layout.addWidget(self.depth_manual_radio, 0, 2)
        depth_layout.addWidget(QLabel("最大深度:"), 1, 2)
        depth_layout.addWidget(self.depth_max_spin, 1, 3)

        layout.addWidget(depth_group)

        # 数值范围设置
        value_group = QGroupBox("数值范围")
        value_layout = QGridLayout(value_group)

        self.value_auto_radio = QRadioButton("自动")
        self.value_manual_radio = QRadioButton("手动")

        self.value_min_spin = QDoubleSpinBox()
        self.value_max_spin = QDoubleSpinBox()

        self.value_min_spin.setRange(-10000, 10000)
        self.value_max_spin.setRange(-10000, 10000)

        self.value_min_spin.setDecimals(2)
        self.value_max_spin.setDecimals(2)

        # 设置当前值
        if self.options["value_range"] == "auto":
            self.value_auto_radio.setChecked(True)
        else:
            self.value_manual_radio.setChecked(True)
            self.value_min_spin.setValue(self.options["value_range"][0])
            self.value_max_spin.setValue(self.options["value_range"][1])

        # 连接信号
        self.value_auto_radio.toggled.connect(lambda checked: self.value_min_spin.setEnabled(not checked))
        self.value_auto_radio.toggled.connect(lambda checked: self.value_max_spin.setEnabled(not checked))
        self.value_min_spin.valueChanged.connect(self._validate_value_range)
        self.value_max_spin.valueChanged.connect(self._validate_value_range)

        value_layout.addWidget(self.value_auto_radio, 0, 0)
        value_layout.addWidget(QLabel("最小值:"), 1, 0)
        value_layout.addWidget(self.value_min_spin, 1, 1)
        value_layout.addWidget(self.value_manual_radio, 0, 2)
        value_layout.addWidget(QLabel("最大值:"), 1, 2)
        value_layout.addWidget(self.value_max_spin, 1, 3)

        layout.addWidget(value_group)

        return tab

    def _on_color_changed(self, index):
        """处理颜色选择变化"""
        if index < len(self.PRESET_COLORS):
            self.options["color"] = self.PRESET_COLORS[index]
        else:
            # 自定义颜色
            color = QColorDialog.getColor()
            if color.isValid():
                self.options["color"] = color.name()
                # 将自定义颜色添加到预设列表
                if color.name() not in self.PRESET_COLORS:
                    self.PRESET_COLORS.append(color.name())
                    # 重新填充颜色下拉框
                    self.color_combo.clear()
                    for c in self.PRESET_COLORS:
                        pixmap = QPixmap(20, 20)
                        pixmap.fill(QColor(c))
                        icon = QIcon(pixmap)
                        self.color_combo.addItem(icon, "")
                        self.color_combo.setItemData(self.color_combo.count() - 1, c, Qt.DecorationRole)
                        self.color_combo.setItemData(self.color_combo.count() - 1, c, Qt.ToolTipRole)
                    self.color_combo.addItem("自定义...")
                    self.color_combo.setCurrentIndex(len(self.PRESET_COLORS) - 1)

    def _update_plot_options(self, plot_type):
        """根据图表类型更新选项可见性"""
        self.options["plot_type"] = plot_type

        # 更新线条设置可见性
        is_line_plot = plot_type in ["曲线图", "散点图"]
        for widget in [self.line_width_spin, self.line_style_combo]:
            widget.setEnabled(is_line_plot)

        # 更新标记设置可见性
        is_marker_plot = plot_type in ["散点图"]
        for widget in [self.marker_combo, self.marker_size_spin]:
            widget.setEnabled(is_marker_plot)

    def _validate_depth_range(self):
        """验证深度范围输入"""
        if self.depth_manual_radio.isChecked() and self.depth_min_spin.value() >= self.depth_max_spin.value():
            self.depth_max_spin.setValue(self.depth_min_spin.value() + 1)

    def _validate_value_range(self):
        """验证数值范围输入"""
        if self.value_manual_radio.isChecked() and self.value_min_spin.value() >= self.value_max_spin.value():
            self.value_max_spin.setValue(self.value_min_spin.value() + 1)

    def get_options(self):
        """获取用户设置"""
        # 更新基本设置
        self.options["plot_type"] = self.plot_type_combo.currentText()
        self.options["line_width"] = self.line_width_spin.value()
        self.options["line_style"] = self.line_style_combo.currentText()
        self.options["marker"] = self.marker_combo.currentText()
        self.options["marker_size"] = self.marker_size_spin.value()
        self.options["opacity"] = self.opacity_slider.value() / 100.0

        # 更新高级设置
        self.options["show_grid"] = self.show_grid_check.isChecked()
        self.options["fill_between"] = self.fill_between_check.isChecked()
        self.options["normalize"] = self.normalize_check.isChecked()
        self.options["log_scale"] = self.log_scale_check.isChecked()
        self.options["colormap"] = self.cmap_combo.currentText()
        self.options["invert_y"] = self.invert_y_check.isChecked()

        # 更新范围设置
        self.options["depth_range"] = "auto" if self.depth_auto_radio.isChecked() else [
            self.depth_min_spin.value(),
            self.depth_max_spin.value()
        ]

        self.options["value_range"] = "auto" if self.value_auto_radio.isChecked() else [
            self.value_min_spin.value(),
            self.value_max_spin.value()
        ]

        return self.options